前面我們做好基本的界面,讓使用者可以從「快速記帳首頁」跳轉到「新增收支記錄」的界面,並為了調整 Core Data Model 的結構又寫了 Migration 程式,終於我們可以繼續完成後續功能:
前面我們已經做好了新增「收支記錄」的界面,也就是使用者將快速記帳轉換成詳細收支記錄的界面,當使用者按下儲存時,我們會將這筆「收支記錄」儲存起來,並標記對應的「快速記帳」為已處理,如下:
override func save() {
guard let quickRecord = quickRecord else {
return
}
let viewContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer!.viewContext
guard let transaction = NSEntityDescription.insertNewObject(forEntityName: String(describing: Transaction.self), into: viewContext) as? Transaction else {
fatalError("Insert Transaction Failed")
}
quickRecord.isProcessed = true
quickRecord.transaction = transaction
transaction.amount = quickRecord.amount
transaction.audioUUID = quickRecord.audioUUID
transaction.createdAt = datePicker.date
transaction.id = UUID()
transaction.location = locationTextField.text ?? ""
transaction.tags = quickRecord.tags
if transactionTypeSegmentedControl.selectedSegmentIndex == 0 {
transaction.type = TransactionType.INCOME
} else {
transaction.type = TransactionType.EXPENSE
}
transaction.quickRecord = quickRecord
try! viewContext.save()
navigationController?.popToRootViewController(animated: true)
}
前段我們儲存資料後,最後我們會用 UINavigationController 的 popToRootViewController 回到首頁,但是以前面所規劃的使用流程來說,我們應該要回到「收支記錄」的首頁:
此時我們就可以利用 UITabBarController 來調整我們的動線。
let rootViewController = UITabBarController()
rootViewController.viewControllers = [
UINavigationController(rootViewController: HomeViewController()),
UINavigationController(rootViewController: TransactionHomeViewController())
]
window?.rootViewController = rootViewController
我們在快速記帳首頁,往右滑動點擊編輯時,會進入新增收支記錄的界面,新增收支記錄的界面是在另一個動線上,如下圖:
使用者從「快速記帳首頁」跳到「新增收支記錄」的界面,其實是從某一個 UINavigationController 跳到另外一個 UINavigationController,當然如果要直接請 UITabBarController 跳到該頁面也可以,但是我們應該要用「Protocol 先行」的做法,讓彼此之間的關聯不要這麼「強烈」。
使用者右滑時,我們應該要從 UITabBarController 中,找到懂得「如何新增收支記錄」的界面,如下:
protocol UnderstandHowToCreateTransaction {
func userWannaCreateTransactionFrom(quickRecord: QuickRecord)
}
任何實做這個 Protocol 的 ViewController,都知道該如何處理這樣的需求,因此我們的「收支記錄首頁」和「新增收支記錄」的界面都要實做這個 Protocol,如下:
extension TransactionHomeViewController: UnderstandHowToCreateTransaction {
func userWannaCreateTransactionFrom(quickRecord: QuickRecord) {
navigationController?.pushViewController(CreateTransactionViewController(quickRecord: quickRecord), animated: true)
}
}
extension CreateTransactionViewController: UnderstandHowToCreateTransaction {
func userWannaCreateTransactionFrom(quickRecord: QuickRecord) {
self.quickRecord = quickRecord
}
}
如此一來,在快速記帳首頁想要請 UITabBarController 切換頁面變得相當容易,而且又不會造成關聯性太高,如下:
func userWannaEdit(quickRecord: QuickRecord) {
if let viewController = tabBarController?.viewControllers?.first(where: { controller in
return (controller as? UINavigationController)?.topViewController is UnderstandHowToCreateTransaction
}) {
tabBarController?.selectedViewController = viewController
((viewController as! UINavigationController).topViewController as! UnderstandHowToCreateTransaction).userWannaCreateTransactionFrom(quickRecord: quickRecord)
}
}
備註:如果硬要說的話,「快速記帳首頁」也「知道如何處理新增收支記錄的需求」,而其處理的方式就是「找出 UITabBarController 中會處理的界面」。最初設計這個 Protocol 就是針對 UITabBarController,因此如果是上述遞迴狀況,我們就要「適當地」停止,不要讓每個界面都去實做這個 Protocol。
程式碼:GitHub
在畫面中,使用者從「快速記帳首頁」點編輯後,會先跳到「收支記錄」的分頁,然後再跳到其中的「新增收支記錄」界面。
目前暫時把「收支記錄首頁」做得跟「快速記帳首頁」一樣,下一篇會專門處理收支記錄首頁的界面。